package my.sorter.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import my.sorter.bean.StaffSecurityInfo;
import my.sorter.bean.filter.StaffFilter;
import my.sorter.dao.baseClient.*;
import my.sorter.dao.model.*;
import my.sorter.dao.privateClient.PStaffMapper;
import my.sorter.service.SecurityService;
import my.sorter.utils.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author zyf10
 */
@Service
public class SecurityServiceImpl implements SecurityService {
    @Autowired
    private StaffMapper staffMapper;
    @Autowired
    private PStaffMapper pStaffMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private StaffRoleMapper staffRoleMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 根据工号获取员工的角色和权限
     *
     * @param jobNumber
     * @return
     */
    @Override
    public StaffSecurityInfo getSecurityInfo(Integer jobNumber) {
        StaffSecurityInfo securityInfo = pStaffMapper.getStaffByJobNumber(jobNumber);
        return securityInfo;
    }

    /**
     * 获取员工的权限json
     *
     * @param jobId
     * @return
     */
    @Override
    public JSONObject getSecurityJson(Integer jobId) {
        JSONObject securityJson = new JSONObject();
        JSONObject roleJson = new JSONObject();
        JSONArray permissionArray = new JSONArray();
        JSONObject unrelated = new JSONObject();
        securityJson.put("unrelated", unrelated);
        List<Map> rows = pStaffMapper.getStaffSecurityJson(jobId);
        if (!CollectionUtils.isEmpty(rows) && rows.size() >= 1) {
            Map sample = rows.get(0);
            securityJson.put("jobNumber", sample.get("job_number"));
            securityJson.put("active", sample.get("active"));
        }
        for (Map row : rows) {
            String role_name = row.get("role_name").toString();
            String role_value = row.get("role_value").toString();
            String permission_name = row.get("permission_name").toString();
            String permission_value = row.get("permission_value").toString();
            //当前角色第一次出现，需要清空permissionArray，并把权限加入其中
            if (!roleJson.containsKey(role_value)) {
                permissionArray = new JSONArray();
                permissionArray.add(permission_value);
                roleJson.put(role_value, permissionArray);
            }
            //当前角色已经存在，只需要取出已有的permissionArray,加入当前权限
            else {
                permissionArray = roleJson.getJSONArray(role_value);
                permissionArray.add(permission_value);
                roleJson.put(role_value, permissionArray);
            }
            //中文名和角色，权限值的对应关系
            if (!unrelated.containsValue(role_value)) {
                unrelated.put(role_name, role_value);
            }
            if (!unrelated.containsValue(permission_value)) {
                unrelated.put(permission_name, permission_value);
            }
        }
        securityJson.put("info", roleJson);
        return securityJson;
    }

    /**
     * 更新员工的权限信息
     *
     * @param securityJson
     * @return
     */
    @Override
    public boolean updateSecurityJson(JSONObject securityJson) {
        List<ConcurrentMap<String, String>> nowSecurities = Collections.synchronizedList(new ArrayList<>());
        Integer jobNumber = securityJson.getInteger("jobNumber");
        boolean active = securityJson.getBooleanValue("active");
        JSONObject info = securityJson.getJSONObject("info");
        Set<Map.Entry<String, Object>> es = info.entrySet();
        pStaffMapper.deleteStaffJson(jobNumber);
        for (Map.Entry e : es) {
            JSONArray permissions = info.getJSONArray(e.getKey().toString());
            for (int i = 0; i < permissions.size(); i++) {
                ConcurrentMap<String, String> nowsecurity = new ConcurrentHashMap<>();
                nowsecurity.put(e.getKey().toString(), permissions.get(i).toString());
                nowSecurities.add(nowsecurity);
                pStaffMapper.createStaffJson(jobNumber, e.getKey().toString());
            }
        }
        return true;
    }

    @Override
    public JSONObject getFullSecurityJson() {
        JSONObject fullSecurity = new JSONObject();
        JSONObject unrelated = new JSONObject();
        JSONArray permissionArray = new JSONArray();
        List<Map> rows = pStaffMapper.getFullSecurityJson();
        fullSecurity.put("unrelated", unrelated);
        for (Map row : rows) {
            String role_name = row.get("role_name").toString();
            String role_value = row.get("role_value").toString();
            String permission_name = row.get("permission_name").toString();
            String permission_value = row.get("permission_value").toString();
            //当前角色第一次出现，需要清空permissionArray，并把权限加入其中
            if (!fullSecurity.containsKey(role_value)) {

                permissionArray = new JSONArray();
                permissionArray.add(permission_value);
                fullSecurity.put(role_value, permissionArray);
            }
            //当前角色已经存在，只需要取出已有的permissionArray,加入当前权限
            else {
                permissionArray = fullSecurity.getJSONArray(role_value);
                permissionArray.add(permission_value);
                fullSecurity.put(role_value, permissionArray);
            }
            //中文名和角色，权限值的对应关系
            if (!unrelated.containsValue(role_value)) {
                unrelated.put(role_name, role_value);
            }
            if (!unrelated.containsValue(permission_value)) {
                unrelated.put(permission_name, permission_value);
            }
        }
        return fullSecurity;
    }


    /**
     * 注册
     *
     * @param staff
     * @return
     */
    @Override
    public boolean register(Staff staff) {
        staff.setId(UUID.randomUUID().toString());
        staff.setActive(false);
        Integer row = staffMapper.insert(staff);
        return row == 1 ? true : false;
    }

    @Override
    public List<Permission> getPermission(String permissionName) {
        PermissionExample example = new PermissionExample();
        if (!StringUtils.isEmpty(permissionName)) {
            example.or().andPermissionNameLike("%" + permissionName + "%");
        }
        return permissionMapper.selectByExample(example);
    }

    @Override
    public boolean deletePermission(List<String> permissionIds) {
        PermissionExample example = new PermissionExample();
        example.or().andIdIn(permissionIds);
        int rows = permissionMapper.deleteByExample(example);
        return rows > 0 ? true : false;
    }

    @Override
    public Boolean createPermission(Permission permission) {
        int rows = permissionMapper.insert(permission);
        return rows == 1 ? true : false;
    }

    @Override
    public Boolean updatePermission(Permission permission) {
        int rows = permissionMapper.updateByPrimaryKeySelective(permission);
        return rows == 1 ? true : false;
    }

    @Override
    public List<Staff> getStaff(StaffFilter filter) {
        StaffExample example = new StaffExample();
        StaffExample.Criteria criteria = example.createCriteria();
        if (!ObjectUtils.isEmpty(filter.getJobNumber())) {
            criteria.andJobNumberEqualTo(filter.getJobNumber());
        }
        if (!StringUtils.isEmpty(filter.getStaffName())) {
            criteria.andStaffNameLike("%" + filter.getStaffName() + "%");
        }
        if (!StringUtils.isEmpty(filter.getDepartment())) {
            criteria.andDepartmentLike("%" + filter.getDepartment() + "%");
        }
        if (!StringUtils.isEmpty(filter.getPost())) {
            criteria.andPostLike("%" + filter.getPost() + "%");
        }
        if (!StringUtils.isEmpty(filter.getActive())) {
            criteria.andActiveEqualTo(filter.getActive());
        }
        List<Staff> staffs = staffMapper.selectByExample(example);
        return staffs;
    }

    @Override
    public Role getStaffRole(String staffId) {
        StaffRoleExample example = new StaffRoleExample();
        example.or().andSIdEqualTo(staffId);
        List<StaffRole> staffRoles = staffRoleMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(staffRoles)) {
            return null;
        }
        Role role = roleMapper.selectByPrimaryKey(staffRoles.get(0).getrId());
        return role;
    }

    @Override
    public List<Permission> getRolePermissions(String roleId) {
        List<Permission> permissions = Collections.synchronizedList(new ArrayList<>());
        RolePermissionExample example = new RolePermissionExample();
        example.or().andRIdEqualTo(roleId);
        List<RolePermission> rps = rolePermissionMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(rps)) {
            for (RolePermission rp : rps) {
                Permission permission = permissionMapper.selectByPrimaryKey(rp.getpId());
                if (!ObjectUtils.isEmpty(permission)) {
                    permissions.add(permission);
                }
            }
        }
        return permissions;
    }

    @Override
    public Boolean updateStaff(Staff staff) {
        return null;
    }

    @Override
    public Boolean createStaff(Staff staff) {
        return null;
    }

    @Override
    public Boolean activeStaff(String staffId) {
        Staff staff = new Staff();
        staff.setId(staffId);
        staff.setActive(true);
        int row = staffMapper.updateByPrimaryKeySelective(staff);
        return row == 1 ? true : false;
    }

    @Override
    public Boolean frozenStaff(String staffId) {
        Staff staff = new Staff();
        staff.setId(staffId);
        staff.setActive(false);
        int row = staffMapper.updateByPrimaryKeySelective(staff);
        return row == 1 ? true : false;
    }

    @Override
    public List<Role> getRole(String roleName) {
        RoleExample example = new RoleExample();
        if (!StringUtils.isEmpty(roleName)) {
            example.or().andRoleNameLike("%" + roleName + "%");
        }
        List<Role> roles = roleMapper.selectByExample(example);
        return roles;
    }

    @Override
    public Boolean updateStaffRole(String staffId, String roleId) {
        Boolean flag = false;
        StaffRoleExample srExample = new StaffRoleExample();
        srExample.or().andSIdEqualTo(staffId);
        staffRoleMapper.deleteByExample(srExample);
        StaffRole staffRole = new StaffRole();
        staffRole.setrId(roleId);
        staffRole.setsId(staffId);
        staffRole.setId(IdUtils.uuid());
        int rows = staffRoleMapper.insert(staffRole);
        if (rows == 1) {
            flag = true;
        }
        return flag;
    }

    @Override
    public Boolean createRole(Role role) {
        int row = roleMapper.insert(role);
        return row == 1 ? true : false;
    }

    @Override
    public Boolean updateRolePermission(String roleId, List<String> permissionIds) {
        Boolean flag = false;
        int sum = 0;
        RolePermissionExample example = new RolePermissionExample();
        example.or().andRIdEqualTo(roleId);
        rolePermissionMapper.deleteByExample(example);
        for (String pid : permissionIds) {
            RolePermission rp = new RolePermission();
            rp.setId(IdUtils.uuid());
            rp.setrId(roleId);
            rp.setpId(pid);
            sum += rolePermissionMapper.insert(rp);
        }
        if (sum == permissionIds.size()) {
            flag = true;
        }
        return flag;
    }

    @Override
    public Boolean deleteRole(String roleId) {
        RoleExample roleExample = new RoleExample();
        roleExample.or().andIdEqualTo(roleId);
        int row = roleMapper.deleteByExample(roleExample);
        return row == 1 ? true : false;
    }
}
